﻿using System;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Controls;
using System.Windows.Forms;

namespace PPSkin
{
    public partial class AudioControlBar : PPControlBase
    {
        private MediaElement mediaElement = new MediaElement();
        private Timer timer = new Timer();

        public bool MusicRandom
        {
            get { return CheckBox_random.Checked; }
            set { CheckBox_random.Checked = value; }
        }

        public AudioControlBar()
        {
            InitializeComponent();
            mediaElement.MediaOpened += new System.Windows.RoutedEventHandler(mediaElement_MediaOpend);
            elementHost.Child = mediaElement;
            mediaElement.Visibility = System.Windows.Visibility.Visible;
            timer.Interval = 500;
            timer.Tick += new EventHandler(Timer_Tick);
            Button_play_pause.Tag = "play";
            TrackBar_volume.Value = 50;
        }

        private void AudioControlBar_Load(object sender, EventArgs e)
        {
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            TrackBar_time.Width = this.Width - 300;
            TrackBar_time.Location = new Point(150, this.Height - TrackBar_time.Height - 3);
            TrackBar_volume.Location = new Point(TrackBar_time.Left + TrackBar_time.Width + 30, this.Height - TrackBar_volume.Height - 3);
            label_totalTime.Location = new Point(TrackBar_time.Left + TrackBar_time.Width - label_totalTime.Width, TrackBar_time.Top - 15);
            label_currentTime.Location = new Point(label_totalTime.Left - label_currentTime.Width, TrackBar_time.Top - 15);
            Button_play_pause.Location = new Point((this.Width - Button_play_pause.Width) / 2, TrackBar_time.Top - Button_play_pause.Height);
            Button_LastSong.Location = new Point(Button_play_pause.Left - Button_LastSong.Width - 10, Button_play_pause.Top + (Button_play_pause.Height - Button_LastSong.Height) / 2);
            Button_NextSong.Location = new Point(Button_play_pause.Right + 10, Button_play_pause.Top + (Button_play_pause.Height - Button_NextSong.Height) / 2);

            pictureBox_musicImage.Location = new Point(10, (this.Height - pictureBox_musicImage.Height) / 2);
            label_musicTitle.Location = new Point(pictureBox_musicImage.Left + pictureBox_musicImage.Width + 5, pictureBox_musicImage.Top + 10);
            label_musicAuther.Location = new Point(label_musicTitle.Left, label_musicTitle.Top + label_totalTime.Height);
        }

        public string FilePath = string.Empty;

        private void mediaElement_MediaOpend(object sender, System.Windows.RoutedEventArgs e)
        {
            FilePath = mediaElement.Source.LocalPath;
            TimeSpan ts = mediaElement.NaturalDuration.TimeSpan;
            label_totalTime.Text = ts.Hours.ToString().PadLeft(2, '0') + ":" + ts.Minutes.ToString().PadLeft(2, '0') + ":" + ts.Seconds.ToString().PadLeft(2, '0');
            TrackBar_time.MaxValue = (int)ts.TotalSeconds;
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            try
            {
                TimeSpan ts = mediaElement.Position;
                label_currentTime.Text = ts.Hours.ToString().PadLeft(2, '0') + ":" + ts.Minutes.ToString().PadLeft(2, '0') + ":" + ts.Seconds.ToString().PadLeft(2, '0');
                if (ts.TotalSeconds <= TrackBar_time.MaxValue)
                {
                    TrackBar_time.Value = (int)ts.TotalSeconds;
                }

                if (mediaElement.Source != null && label_totalTime.Text != "00:00:00" && label_totalTime.Text == label_currentTime.Text)
                {
                    if (MusicPalyComplete != null)
                    {
                        MusicPalyComplete(this, new EventArgs());
                    }
                }
            }
            catch { }
        }

        private void TrackBar_time_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                timer.Stop();
            }
        }

        private void TrackBar_time_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                try
                {
                    mediaElement.Position = new TimeSpan(0, 0, (int)TrackBar_time.Value);
                }
                catch { }
                timer.Start();
            }
        }

        public event EventHandler MusicPalyComplete;

        private void TrackBar_time_ValueChanged(object sender, EventArgs e)
        {
        }

        private void TrackBar_volume_ValueChanged(object sender, EventArgs e)
        {
            mediaElement.Volume = (double)TrackBar_volume.Value / 100;
        }

        private void Button_play_pause_Click(object sender, EventArgs e)
        {
            if ((string)Button_play_pause.Tag == "play")
            {
                if (mediaElement.Source != null)
                {
                    mediaElement.Play();
                    Button_play_pause.Tag = "pause";
                    this.BeginInvoke(new MethodInvoker(() => { Button_play_pause.IcoRegular = PPSkinResources.pause; Button_play_pause.IcoIn = PPSkinResources.pause; Button_play_pause.IcoDown = PPSkinResources.pause; }));
                    timer.Start();
                }
            }
            else
            {
                if (mediaElement.Source != null)
                {
                    mediaElement.Pause();
                    Button_play_pause.Tag = "play";
                    this.BeginInvoke(new MethodInvoker(() => { Button_play_pause.IcoRegular = PPSkinResources.play; Button_play_pause.IcoIn = PPSkinResources.play; Button_play_pause.IcoDown = PPSkinResources.play; }));
                    timer.Stop();
                }
            }
        }

        public event EventHandler LastSongClicked;

        private void Button_LastSong_Click(object sender, EventArgs e)
        {
            if (LastSongClicked != null)
            {
                LastSongClicked(this, new EventArgs());
            }
        }

        public event EventHandler NextSongClicked;

        private void Button_NextSong_Click(object sender, EventArgs e)
        {
            if (NextSongClicked != null)
            {
                NextSongClicked(this, new EventArgs());
            }
        }

        public void Play()
        {
            if (mediaElement.Source != null)
            {
                mediaElement.Play();
                Button_play_pause.Tag = "pause";
                this.Invoke(new MethodInvoker(() => { Button_play_pause.IcoRegular = PPSkinResources.pause; Button_play_pause.IcoIn = PPSkinResources.pause; Button_play_pause.IcoDown = PPSkinResources.pause; }));
                timer.Start();
            }
        }

        public void Pause()
        {
            if (mediaElement.Source != null)
            {
                mediaElement.Play();
                Button_play_pause.Tag = "pause";
                this.Invoke(new MethodInvoker(() => { Button_play_pause.IcoRegular = PPSkinResources.pause; Button_play_pause.IcoIn = PPSkinResources.pause; Button_play_pause.IcoDown = PPSkinResources.pause; }));
                timer.Start();
            }
        }

        private string CurrentMusicPath = "";

        public void LoadMusic(string path)
        {
            if (!File.Exists(path))
            {
                return;
            }

            string filetype = Path.GetExtension(path);
            if (filetype.ToLower() != ".mp3" && filetype.ToLower() != ".flac")
            {
                return;
            }

            string filename = Path.GetFileNameWithoutExtension(path);

            MusicTags tags = ReadMp3(path);

            if (!String.IsNullOrEmpty(tags.Title))
            {
                label_musicTitle.Text = tags.Title;
            }
            else
            {
                label_musicTitle.Text = filename;
            }

            if (!String.IsNullOrEmpty(tags.Artist))
            {
                label_musicAuther.Text = tags.Artist;
            }
            else
            {
                label_musicAuther.Text = "";
            }

            if (tags.image != null)
            {
                pictureBox_musicImage.Image = tags.image.Clone() as Bitmap;
            }
            else
            {
                pictureBox_musicImage.Image = PPSkinResources.music;
            }

            //Mp3Info mp3info = getMp3Info(path);

            //if (!String.IsNullOrEmpty(mp3info.Title))
            //{
            //    label_musicTitle.Text = mp3info.Title;
            //}
            //else
            //{
            //    label_musicTitle.Text = filename;
            //}

            //if (!String.IsNullOrEmpty(mp3info.Artist))
            //{
            //    label_musicAuther.Text = mp3info.Artist;
            //}
            //else
            //{
            //    label_musicAuther.Text = "";
            //}

            mediaElement.Source = new Uri(path, UriKind.Absolute);
            mediaElement.LoadedBehavior = MediaState.Manual;

            CurrentMusicPath = path;
        }

        public struct MusicTags
        {
            public string Title;//标题
            public string Artist;//艺术家
            public string Album;//专辑
            public string Time;//时间
            public string Comment;//注释
            public System.Drawing.Image image;//专辑图片
        }

        public static MusicTags ReadMp3(string path)
        {
            //int mp3TagID = 0;
            MusicTags tags = new MusicTags();
            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
            byte[] buffer = new byte[10];
            // fs.Read(buffer, 0, 128);
            string mp3ID = "";

            fs.Seek(0, SeekOrigin.Begin);
            fs.Read(buffer, 0, 10);
            int size = (buffer[6] & 0x7F) * 0x200000 + (buffer[7] & 0x7F) * 0x4000 + (buffer[8] & 0x7F) * 0x80 + (buffer[9] & 0x7F);
            //int size = (buffer[6] & 0x7F) * 0X200000 * (buffer[7] & 0x7f) * 0x4000 + (buffer[8] & 0x7F) * 0x80 + (buffer[9]);
            mp3ID = Encoding.Default.GetString(buffer, 0, 3);
            if (mp3ID.Equals("ID3", StringComparison.OrdinalIgnoreCase))
            {
                //mp3TagID = 1;
                //如果有扩展标签头就跨过 10个字节
                if ((buffer[5] & 0x40) == 0x40)
                {
                    fs.Seek(10, SeekOrigin.Current);
                    size -= 10;
                }
                tags = ReadFrame(fs, size);
            }
            else if (mp3ID.Equals("fLa", StringComparison.OrdinalIgnoreCase))
            {
            }
            return tags;
        }

        public static MusicTags ReadFrame(FileStream fs, int size)
        {
            MusicTags ID3V2 = new MusicTags();
            byte[] buffer = new byte[10];
            while (size > 0)
            {
                //fs.Read(buffer, 0, 1);
                //if (buffer[0] == 0)
                //{
                //    size--;
                //    continue;
                //}
                //fs.Seek(-1, SeekOrigin.Current);
                //size++;
                //读取标签帧头的10个字节
                fs.Read(buffer, 0, 10);
                size -= 10;
                //得到标签帧ID
                string FramID = Encoding.Default.GetString(buffer, 0, 4);
                //计算标签帧大小，第一个字节代表帧的编码方式
                int frmSize = 0;

                frmSize = buffer[4] * 0x1000000 + buffer[5] * 0x10000 + buffer[6] * 0x100 + buffer[7];
                if (frmSize == 0)
                {
                    //就说明真的没有信息了
                    break;
                }
                //bFrame 用来保存帧的信息
                byte[] bFrame = new byte[frmSize];
                fs.Read(bFrame, 0, frmSize);
                size -= frmSize;
                string str = GetFrameInfoByEcoding(bFrame, bFrame[0], frmSize - 1);
                if (FramID.CompareTo("TIT2") == 0)
                {
                    ID3V2.Title = str;
                }
                else if (FramID.CompareTo("TPE1") == 0)
                {
                    ID3V2.Artist = str;
                }
                else if (FramID.CompareTo("TALB") == 0)
                {
                    ID3V2.Album = str;
                }
                else if (FramID.CompareTo("TIME") == 0)
                {
                    ID3V2.Time = str;
                }
                else if (FramID.CompareTo("COMM") == 0)
                {
                    ID3V2.Comment = str;
                }
                else if (FramID.CompareTo("APIC") == 0)
                {
                    //MessageBox.Show("有图片信息");

                    try
                    {
                        int i = 0;
                        while (true)
                        {
                            if (137 == bFrame[i] && 80 == bFrame[i + 1])
                            {
                                //在
                                break;
                            }
                            i++;
                        }

                        byte[] imge = new byte[frmSize - i];
                        fs.Seek(-frmSize + i, SeekOrigin.Current);
                        fs.Read(imge, 0, imge.Length);
                        MemoryStream ms = new MemoryStream(imge);

                        System.Drawing.Image img = System.Drawing.Image.FromStream(ms);

                        ID3V2.image = img;
                    }
                    catch { }

                    //FileStream save = new FileStream(@"C:\Users\PC-DELL\Desktop\22.jpeg", FileMode.Create);
                    //img.Save(save, System.Drawing.Imaging.ImageFormat.Jpeg);

                    //MessageBox.Show("成功");
                    //}
                }
            }
            return ID3V2;
        }

        public static string GetFrameInfoByEcoding(byte[] b, byte conde, int length)
        {
            string str = "";
            switch (conde)
            {
                case 0:
                    str = Encoding.GetEncoding("ISO-8859-1").GetString(b, 1, length);
                    break;

                case 1:
                    str = Encoding.GetEncoding("UTF-16LE").GetString(b, 1, length);
                    break;

                case 2:
                    str = Encoding.GetEncoding("UTF-16BE").GetString(b, 1, length);
                    break;

                case 3:
                    str = Encoding.UTF8.GetString(b, 1, length);
                    break;
            }
            return str;
        }

        private void CheckBox_random_CheckedChanged(object sender, EventArgs e)
        {
        }
    }
}